package my.ts.code.net;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import my.ts.code.KLog;

public class SocketHandler {

	private String host;

	private int port;
	//
	private String altHost;

	private Socket socket;

	private DataInputStream ips;

	private DataOutputStream ops;

	private InComingListener listener;

	public SocketHandler(String host, int port, String altHost) {
		this.host = host;
		this.port = port;
		this.altHost = altHost;

	}

	public void setListener(InComingListener listener) {
		this.listener = listener;
	}

	public boolean open() throws IOException {
		try {
			KLog.log("-socket://" + host + ":" + port);
			socket = new Socket(host, port);
			KLog.log("Connected");
		} catch (Exception ex) {
			KLog.log("--------------------------------");
			KLog.log("   Main host fail, try a gain with alt-host");
			KLog.log("-socket://" + altHost + ":" + port);
			ex.printStackTrace();
			try {
				socket = new Socket(altHost, port);
			} catch (Exception ex1) {
				KLog.log("NO CONNECTION");
				// if (listener != null)
				// listener.connectionError(true);
				return false;
			}
		}
		ips = new DataInputStream(socket.getInputStream());
		ops = new DataOutputStream(socket.getOutputStream());
		return true;
	}

	public void close() throws Exception {
		if (socket != null)
			socket.close();
		if (ips != null)
			ips.close();
		if (ops != null)
			ops.close();
		//
		ips = null;
		ops = null;
		socket = null;
	}

	public void sendMessage(String mess) throws IOException {

		// String message =
		// "url:http://210.211.98.84/webicm/ts/MusicCategory.tm\n"
		// + "method:POST\n" + "req:\n" + "par:Accept-Encoding:gzip\n";
		// ops.write(message.getBytes());
		synchronized (ops) {

			try {
				PrintWriter writer = new PrintWriter(ops, true);
				writer.println(mess);
			} catch (Exception e) {
				// TODO: handle exception
				System.out.println("CANNOT SEND");
			}
		}

	}

	public String receivedMessage() throws Exception {
		synchronized (ips) {

			try {

				byte[] magic = new byte[2];
				String strMagic = readLine(magic);
				System.out.println("STR MAGIC=" + strMagic);

				if (!strMagic.equals("TS")) {
					return null;
				}

				byte[] type = new byte[1];
				ips.read(type);
				System.out.println("TYPE=" + type[0]);

				int length = readInt();
				System.out.println("L=" + length);

				String rs = "";

				byte[] body = new byte[length];
				readBuffer(body);

				rs += new String(body);
				System.out.println("RS=" + rs);

				return rs;
			} catch (Exception ex) {
				ex.printStackTrace();
				throw ex;
			}

		}
	}

	private String readLine(byte[] buff) throws IOException {
		ips.read(buff);
		return new String(buff);
	}

	/**
	 * Note: the term 'packet' here refers to a message, not a TCP packet
	 * (although in almost all cases the two will be synonymous). This is to
	 * avoid confusion with a 'message' - the actual discussion packet.
	 * 
	 * @param body
	 * @param service
	 * @param status
	 * @param sessionId
	 * @throws IOException
	 */

	// -----------------------------------------------------------------
	// Reads an entire buffer of data, allowing for blocking (thread doc.
	// se doi o day den khi nao doc duoc du lieu thi thoi)
	// Returns bytes read (should be == to buffer size) or negative
	// bytes read if 'EOF' encountered.
	// -----------------------------------------------------------------
	private int readBuffer(byte[] buff) throws IOException {

		int p = 0, r = 0;
		while (p < buff.length) {
			r = ips.read(buff, p, buff.length - p);
			// System.out.println("doc gi "+r);
			if (r < 0)
				return (p + 1) * -1;
			else
				p += r;
		}

		// KLog.log("packet "+new String(buff));
		return p;
	}

	private int readInt() throws IOException {
		return ips.readInt();
	}
}
